package com.asiainfo.ai.admin.utils;

import cn.hutool.core.util.ArrayUtil;
import com.asiainfo.ai.admin.controller.vo.TreeNode;
import com.asiainfo.ai.admin.exception.BaseException;
import com.asiainfo.ai.admin.exception.ErrorType;
import com.google.common.collect.Maps;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Description: Date: 2019-04-01 22:30
 *
 * @author liyi
 */
public class TreeNodeConverter {
    private static final String ID_FIELD = "id";
    private static final String NAME_FIELD = "name";
    private static final String PID_FIELD = "pid";
    private static final String DESCRIPTION = "desc";

    /**
     * 根据模块列表，生成树形结构集合
     *
     * @param list          需要转换的list集合
     * @param parentId      父节点id
     * @param additionField 附加信息字段
     * @return 返回树形结构数据集合
     */
    public static <T> List<TreeNode> convert(Collection<T> list, String parentId, String[] additionField) {
        return convert(list, parentId, ID_FIELD, PID_FIELD, NAME_FIELD, DESCRIPTION, additionField);
    }

    /**
     * 根据模块列表，生成树形结构集合
     *
     * @param list          需要转换的list集合
     * @param parentId      父节点id
     * @param idField       id字段
     * @param nameField     名称字段
     * @param pidField      pid字段
     * @param additionField 附加信息字段
     * @return 返回树形结构数据集合
     */
    public static <T> List<TreeNode> convert(Collection<T> list,
                                             String parentId,
                                             String idField,
                                             String pidField,
                                             String nameField,
                                             String description,
                                             String[] additionField) {
        return list.stream()
                .filter(it -> getFieldValue(it, pidField).equalsIgnoreCase(parentId))
                .map(it -> {
                    String id = getFieldValue(it, idField);
                    Map<String, Object> additionMap = Maps.newHashMap();
                    if (ArrayUtil.isNotEmpty(additionField)) {
                        for (String field : additionField) {
                            additionMap.put(field, getFieldValue(it, field));
                        }
                    }
                    return TreeNode.builder()
                            .id(id)
                            .pid(parentId)
                            .name(getFieldValue(it, nameField))
                            .desc(description)
                            .children(convert(list, id, idField, pidField, nameField, description, additionField))
                            .addition(additionMap)
                            .build();
                })
                .collect(Collectors.toList());
    }

    private static <T> String getFieldValue(T t, String fieldName) {
        Field field = ReflectionUtils.findField(t.getClass(), fieldName);
        if (null == field) {
            throw new BaseException(ErrorType.SYSTEM_ERROR, "树形结构转换失败，字段" + fieldName + "不存在");
        }
        ReflectionUtils.makeAccessible(field);
        return String.valueOf(ReflectionUtils.getField(field, t));
    }
}
